package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
	"ebbflow/src/consensus"
	"ebbflow/src/config"
	"ebbflow/src/message"
	"ebbflow/src/turritopsis"
	"ebbflow/logger"
)

const (
	helpText_ebbflow_server = `
EbbFlow Protocol Server with Performance Logging
Usage: ebbflow_server [NodeID]
`
)

var (
	nodeID     = flag.Int("id", 0, "Node ID")
	totalNodes = flag.Int("n", 6, "Total number of nodes")
	faultyNodes = flag.Int("f", 1, "Number of faulty nodes")
	epochs    = flag.Int("epochs", 30, "Number of epochs to run")
	r         = flag.Int("r", 5, "ADKR execution interval (every R epochs)")
	verbose    = flag.Bool("v", false, "Verbose logging")
	enableLogger = flag.Bool("logger", true, "Enable performance logging")
	logDir    = flag.String("logdir", "logger", "Log directory")
)

func main() {
	flag.Parse()
	
	if *nodeID < 0 || *nodeID >= *totalNodes {
		log.Fatal("Invalid node ID")
	}
	
	if *faultyNodes >= *totalNodes/2 {
		log.Fatal("Too many faulty nodes")
	}
	
	log.Printf("Starting EbbFlow Protocol Server with Performance Logging")
	log.Printf("Node ID: %d, Total Nodes: %d, Faulty Nodes: %d, Epochs: %d, R: %d", 
		*nodeID, *totalNodes, *faultyNodes, *epochs, *r)
	
	// Load configuration
	config.LoadConfig()
	
	// Create performance logger
	var ebbLogger *logger.EbbFlowLogger
	var err error
	if *enableLogger {
		ebbLogger, err = logger.NewEbbFlowLogger(*nodeID, *logDir)
		if err != nil {
			log.Printf("Warning: Failed to create performance logger: %v", err)
		} else {
			log.Printf("Performance logging enabled, logs will be saved to: %s", *logDir)
		}
	}
	
	// Create communication channels
	msgInCh := make(chan message.ReplicaMessage, 1000)
	msgOutCh := make(chan message.ReplicaMessage, 1000)
	
	// Create integrated consensus
	consensus := consensus.NewEbbFlowConsensus(
		*nodeID, *totalNodes, *faultyNodes,
		msgInCh, msgOutCh,
	)
	
	// Start consensus
	if err := consensus.Start(); err != nil {
		log.Fatalf("Failed to start consensus: %v", err)
	}
	
	// Start performance monitoring
	go monitorPerformance(consensus, ebbLogger)
	
	// Setup signal handling
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	
	// Wait for signal or completion
	select {
	case <-sigChan:
		log.Printf("Received shutdown signal")
	case <-time.After(time.Duration(*epochs) * time.Second):
		log.Printf("Completed %d epochs", *epochs)
	}
	
	// Stop consensus
	consensus.Stop()
	
	// Stop logger
	if ebbLogger != nil {
		ebbLogger.Stop()
		log.Printf("Performance logs saved to: %s", *logDir)
	}
	
	log.Printf("EbbFlow Server stopped")
}

// monitorPerformance 监控性能指标
func monitorPerformance(consensus *consensus.EbbFlowConsensus, ebbLogger *logger.EbbFlowLogger) {
	ticker := time.NewTicker(30 * time.Second)
	defer ticker.Stop()
	
	epoch := 0
	for {
		select {
		case <-ticker.C:
			epoch++
			
			// 获取性能指标 (这里需要从consensus获取实际数据)
			tps := getCurrentTPS(consensus)
			latency := getCurrentLatency(consensus)
			batchSize := 1000 // 默认批次大小
			txSize := 250     // 默认交易大小
			
			if ebbLogger != nil {
				ebbLogger.LogPerformance(tps, latency, epoch, batchSize, txSize)
			}
			
			log.Printf("Performance [Epoch %d]: TPS=%.2f, Latency=%dms", epoch, tps, latency)
		}
	}
}

// getCurrentTPS 获取当前TPS (模拟实现)
func getCurrentTPS(consensus *consensus.EbbFlowConsensus) float64 {
	// 这里应该从consensus获取实际的TPS数据
	// 目前返回模拟数据
	return 1000.0 + float64(time.Now().Unix()%1000)
}

// getCurrentLatency 获取当前延迟 (模拟实现)
func getCurrentLatency(consensus *consensus.EbbFlowConsensus) int64 {
	// 这里应该从consensus获取实际的延迟数据
	// 目前返回模拟数据
	return int64(20 + time.Now().Unix()%50)
}
